using System;
using System.Collections.Generic;
using MSOffice = Microsoft.Office.Core;
using MSOutlook = Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Tools.Outlook;

using System.ComponentModel;
using System.Windows.Forms;

namespace Microsoft.Sample.Outlook.Utility
{
    public sealed class CommandBarManager
	{
        static ISynchronizeInvoke _invokeSync = null;

		MSOutlook.Inspectors _inspectors;
		MSOutlook.Explorers _explorers;
        List<CommandBar> _commandBars = new List<CommandBar>();

		public CommandBarManager(Microsoft.Office.Tools.Outlook.OutlookAddIn app)
			
		{
		}

		public CommandBarManager(MSOutlook.Application app)
		{
			_inspectors = app.Inspectors;
			_inspectors.NewInspector += new MSOutlook.InspectorsEvents_NewInspectorEventHandler(OnNewInspector);
			_explorers = app.Explorers;
			_explorers.NewExplorer += new MSOutlook.ExplorersEvents_NewExplorerEventHandler(OnNewExplorer);

            if (_invokeSync == null)
            {
                Control c = new Control();
                c.CreateControl();
                IntPtr p = c.Handle;
                _invokeSync = c;
            }
		}

        public void Shutdown()
        {
            _inspectors.NewInspector -= new MSOutlook.InspectorsEvents_NewInspectorEventHandler(OnNewInspector);
            _explorers.NewExplorer -= new MSOutlook.ExplorersEvents_NewExplorerEventHandler(OnNewExplorer);

            foreach (MSOutlook.Explorer explorer in _explorers)
            {
                foreach (CommandBar t in _commandBars)
                    t.Detach(new WindowAdapter(explorer));
            }

            foreach (MSOutlook.Inspector inspector in _inspectors)
            {
                foreach (CommandBar t in _commandBars)
                    t.Detach(new WindowAdapter(inspector));
            }

        }

		void OnNewExplorer(MSOutlook.Explorer explorer)
		{
            foreach (CommandBar t in _commandBars)
				t.Attach(explorer);
		}

		void OnNewInspector(MSOutlook.Inspector inspector)
		{
            foreach (CommandBar t in _commandBars)
				t.Attach(inspector);
		}

		public void RegisterCommandBar(CommandBar commandbar)
		{
            _commandBars.Add(commandbar);

			foreach (MSOutlook.Explorer explorer in _explorers)
                commandbar.Attach(explorer);
			foreach (MSOutlook.Inspector inspector in _inspectors)
                commandbar.Attach(inspector);
		}

        //When using WordMail, the events fired by toolbar and menu items arrive on a background thread
        //CommandBarManager uses a ISynchronizeInvoke object (a control, set in the constructor) 
        //to dynamically invoke any toolbar or menu events on the correct thread
        internal static void DynamicInvoke(Delegate del, params object[] delParams)
        {
            if (_invokeSync == null)
                throw new NullReferenceException("You must create an instance of the CommandBarManager before calling the static DyanmicInvoke method");

            if (_invokeSync.InvokeRequired)
            {
                _invokeSync.Invoke(del, delParams);
            }
            else
            {
                del.DynamicInvoke(delParams);
            }
        }

	}
}
